<?php

namespace app\libs\DianDianPaySDK;

class SignatureHandler
{
    private $key;
    private $is_private;

    public function __construct(string $key, string $key_type = 'private')
    {
        // 初始化签名/验签类
        if ($key_type == 'private') {
            // 生成私钥
            //$pem_key = "-----BEGIN PRIVATE KEY-----\n" . wordwrap($key, 64, "\n", true) . "\n-----END PRIVATE KEY-----";
            //dump($pem_key);
            $this->key = openssl_pkey_get_private($key);
            $this->is_private = true;
        } elseif ($key_type == 'public') {
            // 生成公钥
           // $pem_key = "-----BEGIN PUBLIC KEY-----\n" . wordwrap($key, 64, "\n", true) . "\n-----END PUBLIC KEY-----";
            $this->key = openssl_pkey_get_public($key);
            $this->is_private = false;
        } else {
            throw new \Exception("Invalid key_type. Must be 'private' or 'public'.");
        }
    }

    public function generate_signature(string $merchant_id, string $timestamp, string $timezone, array $body): string
    {
        if (!$this->is_private) {
            throw new \Exception("Key must be private to generate signature.");
        }

        // 拼接签名内容
        $body_str = json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        $sign_content = "$merchant_id.$timestamp.$timezone.$body_str";

        // 生成签名
        $signature = null;
        openssl_sign($sign_content, $signature, $this->key, OPENSSL_ALGO_SHA256);

        // 返回 Base64 编码的签名字符串
        return base64_encode($signature);
    }

    public function verify_signature(string $merchant_id, string $timestamp, string $timezone, array $body, string $received_signature): bool
    {
        if ($this->is_private) {
            throw new \Exception("Key must be public to verify signature.");
        }

        // 拼接签名内容
        $body_str = json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        $sign_content = "$merchant_id.$timestamp.$timezone.$body_str";
        // 解码收到的签名
        $decoded_signature = base64_decode($received_signature);

        // 验证签名
        $result = openssl_verify($sign_content, $decoded_signature, $this->key, OPENSSL_ALGO_SHA256);

        // 如果验证成功，返回 true，否则返回 false
        return $result === 1;
    }
}